package com.blz.flare.crawler;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The configuration bean for the crawler.
 * 
 * @author pchapman
 * @author jeremy.arnold
 */
public class CrawlerConfig {
    private Logger logger = LoggerFactory.getLogger(getClass());

    private List<Pattern> blackList = new LinkedList<Pattern>();
    private List<URI> startURIs = new LinkedList<URI>();
    private List<Pattern> whiteList = new LinkedList<Pattern>();
    
    private Map<String, String> metadataFields = new HashMap<String, String>();
    private URL solrURL;
    private int threadCount;
    private int depth;

    /**
     * Add a pattern to the blacklist.
     * @param regexpattern a pattern for the blacklisted item
     */
	public void addBlackListing(String regexpattern) {
		blackList.add(Pattern.compile(regexpattern));
	}

    /**
     * @return a list of {@link Pattern}s that have been blacklisted
     */
	public List<Pattern> getBlackList() {
		return Collections.unmodifiableList(blackList);
	}

    /**
     * Set the patterns that should be blacklisted.
     * @param regexpatterns the patterns to blacklist
     */
	public void setBlackList(String[] regexpatterns) {
		for (String rp : regexpatterns) {
			addBlackListing(rp);
		}
	}

    /**
     * Add a metadata field.
     *
     * @param metadatafield the metadata field
     * @param indexfield the index field
     */
	public void addMetaDataField(String metadatafield, String indexfield) {
		this.metadataFields.put(metadatafield, indexfield);
	}
	/**
	 * @return A map of metadata fields to index.  The key is the name of the metadata
	 * field.  The value is the name of the index.
	 */
	public Map<String, String> getMetaDataFields() {
		return Collections.unmodifiableMap(metadataFields);
	}

    /**
     * @param fields the metadatafields to set
     */
	public void setMetaDataFields(Map<String, String> fields) {
		this.metadataFields = fields;
	}

    /**
     * @return the solr url
     */
	public URL getSolrURL() {
		return solrURL;
	}

    /**
     * @param url the solr url to set
     */
	public void setSolrURL(URL url) {
		this.solrURL = url;
	}

    /**
     * @param url the solr url to set
     */
	public void setSolrURL(String url) {
		try {
			setSolrURL(new URL(url));
		} catch (MalformedURLException e) {
			logger.error("Invalid URL {}", url, e);
			throw new IllegalArgumentException("Invalid URL", e);
		}
	}

    /**
     * Add a url to start with.
     *
     * @param uri the URI to start with
     */
	public void addStartURI(String uri) {
		try {
			startURIs.add(new URI(uri));
		} catch (URISyntaxException e) {
			logger.error("Invalid URI {}", uri, e);
			throw new IllegalArgumentException("Invalid URI", e);
		}
	}

    /**
     * @return a list of {@link URI}s to start with.
     */
	public List<URI> getStartURIs() {
		return Collections.unmodifiableList(startURIs);
	}

    /**
     * @param uris an array of URIs to start with
     */
	public void setStartURIs(String[] uris) {
		for (String uri : uris) {
			addStartURI(uri);
		}
	}

    /**
     * @return the number of threads to use
     */
	public int getThreadCount() {
		return threadCount;
	}

    /**
     * @param count the number of threads to use
     */
	public void setThreadCount(int count) {
		this.threadCount = count;
	}

    /**
     * Add a regex pattern.
     * @param regexpattern  the pattern to add
     */
	public void addWhiteListing(String regexpattern) {
		whiteList.add(Pattern.compile(regexpattern));
	}

    /**
     * @return a list of {@link Pattern}s that have been whiteListed.
     */
	public List<Pattern> getWhiteList() {
		return Collections.unmodifiableList(whiteList);
	}

    /**
     * @param regexpatterns an array of strings to use as regex patterns
     */
	public void setWhiteList(String[] regexpatterns) {
		for (String rp : regexpatterns) {
			addWhiteListing(rp);
		}
	}

    /**
     * @return the depth to crawl
     */
    public int getDepth() {
        return depth;
    }

    /**
     * @param depth the depth to crawl
     */
    public void setDepth(int depth) {
        this.depth = depth;
    }
}
